#include "application.h"
#include "boards/board.h"
#include "boards/system_info.h"
#include <cstring>
#include <esp_log.h>
#include <cJSON.h>
#include <driver/gpio.h>
#include <arpa/inet.h>
#include <esp_event.h>
#include <web_socket.h>
#include "boards/websocket_protocol.h"



#define TAG "Application"


Application::Application() {
    event_group_ = xEventGroupCreate();
}

Application::~Application() {
    vEventGroupDelete(event_group_);
}


void Application::StartListening() {
   
}

void Application::StopListening() {
    
}

void Application::Start() {
    /* Setup the board */
    auto& board = Board::GetInstance();
    /* Setup the display */
   
    /* Setup the audio codec */
   
    /* Start the main loop */
    xTaskCreate([](void* arg) {
        Application* app = (Application*)arg;
        app->MainLoop();
        vTaskDelete(NULL);
    }, "main_loop", 4096 * 2, this, 2, nullptr);

    /* Wait for the network to be ready */
    printf("开始配网...\n");
    board.StartNetwork();
    printf("配网结束\n");

    vTaskDelay(pdMS_TO_TICKS(1000));
    printf("开始连接socker Server...\n");
    WebsocketProtocol* protocol = new WebsocketProtocol();
    protocol->OpenAudioChannel();
    printf("连接socker Server end\n");
}


// The Main Loop controls the chat state and websocket connection
// If other tasks need to access the websocket or chat state,
// they should use Schedule to call this function
void Application::MainLoop() {
    while (true) {
        // 等待事件组中特定事件位被设置
        auto bits = xEventGroupWaitBits(event_group_,
            SCHEDULE_EVENT | AUDIO_INPUT_READY_EVENT | AUDIO_OUTPUT_READY_EVENT,
            pdTRUE,  //事件位被设置并函数返回后，自动清除事件位
            pdFALSE, //任意一个事件位被设置 函数就会返回
            portMAX_DELAY); //任务超时时间，portMAX_DELAY：任务将无限等待

        if (bits & AUDIO_INPUT_READY_EVENT) {
            InputAudio();
        }
        if (bits & AUDIO_OUTPUT_READY_EVENT) {
            OutputAudio();
        }
        if (bits & SCHEDULE_EVENT) {
            mutex_.lock();
            std::list<std::function<void()>> tasks = std::move(main_tasks_);
            mutex_.unlock();
            for (auto& task : tasks) {
                task();
            }
        }
    }
}


void Application::OutputAudio() {
    
}

void Application::InputAudio() {

}
